#ifndef _AURORAL_TCP_CLIENT_H_
#define _AURORAL_TCP_CLIENT_H_

#include <boost/asio.hpp>
#include <boost/cstdint.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
#include <string>
#include <queue>
#include <set>
#include <boost/enable_shared_from_this.hpp>

namespace auroral { namespace net {

using namespace boost;
using namespace boost::asio::ip;

class TcpServer;

class TcpSession: public boost::enable_shared_from_this<TcpSession>
{
public:
	typedef boost::shared_ptr<TcpSession> pointer;

	TcpSession(boost::asio::io_service& io_service);

	virtual ~TcpSession();

	virtual pointer clone() = 0; // return a pointer to a new TopConnection

	virtual tcp::socket& socket();

	virtual void start();

	virtual void async_write(const std::string &message);

protected:

	// process the data restored in @response_
	virtual void process_read() = 0;

	virtual void push_write_queue(const std::string message);

	virtual void handle_read(const boost::system::error_code& err);

	virtual void handle_write(const boost::system::error_code& err/*error*/,
		size_t /*bytes_transferred*/);

	tcp::socket socket_;
	std::queue<std::string> messages_;
	boost::asio::streambuf response_;
	boost::asio::io_service::strand strand_;
	TcpServer *parentServer_;
	bool writting;
private:
};

class TcpServer
{
public:
	TcpServer(boost::asio::io_service& io_service, TcpSession::pointer TcpSession, int16_t port);
	virtual ~TcpServer();

protected:
	virtual void start_accept();

	virtual void handle_accept(TcpSession::pointer new_connection,
		const boost::system::error_code& error);

	boost::shared_ptr<TcpSession> TcpSession_;
	tcp::acceptor acceptor_;
};

} }; // namespace auroral::net

#endif // _AURORAL_TCP_CLIENT_H_